//
// Created by jaesonzhang on 2024/3/20.
//

#ifndef CPPSQLITE_EVENTBUS_H
#define CPPSQLITE_EVENTBUS_H

#include "Event.h"
#include "ThreadSafeQueue.h"
#include <list>
#include <typeindex>
#include <unordered_map>
#include <mutex>
#include <thread>
#include <functional>
#include <vector>

class EventBus {
 public:
  static EventBus &getInstance() {
    static EventBus instance;
    return instance;
  }

  EventBus(const EventBus &) = delete;

  EventBus &operator=(const EventBus &) = delete;

  ~EventBus() {
  }

  void subscribe(std::type_index eventType, EventListener *listener) {
    std::lock_guard<std::mutex> lock(mutex);
    listeners[eventType].push_back(listener);
  }

  void unsubscribe(std::type_index eventType, EventListener *listener) {
    std::lock_guard<std::mutex> lock(mutex);
    auto &eventListeners = listeners[eventType];
    eventListeners.remove(listener);
  }

  void post(const Event &event) {
    std::lock_guard<std::mutex> lock(mutex);
    std::type_index eventType(typeid(event));
    auto it = listeners.find(eventType);
    if (it != listeners.end()) {
      for (EventListener *listener: it->second) {
        listener->onEvent(event);
      }
    }
  }

 private:
  std::mutex mutex;
  std::unordered_map<std::type_index, std::list<EventListener *>> listeners;

  EventBus() {
  }

};

#endif //CPPSQLITE_EVENTBUS_H
